package com.spzx.product.listener;

import com.rabbitmq.client.Channel;
import com.spzx.common.rabbit.constant.MqConst;
import com.spzx.product.domain.SkuLockVo;
import com.spzx.product.domain.SkuStockVo;
import com.spzx.product.mapper.SkuStockMapper;
import com.spzx.product.service.SkuStockService;
import jakarta.annotation.Resource;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;


@Component
public class StuStockListener {


    @Resource
    private SkuStockMapper skuStockMapper;

    @Autowired
    private RedisTemplate redisTemplate;


    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(durable = "true", value = MqConst.EXCHANGE_PRODUCT),
            value = @Queue(durable = "true", value = MqConst.QUEUE_UNLOCK),
            key = {MqConst.ROUTING_UNLOCK}
    ))
    public void unlockStock(Channel channel, String orderNo, Message message) throws IOException {

        String key = "sku:info:lock:" + orderNo;
        //如果成功锁定库存，就将dataKey保存到redis中
        String dataKey = "sku:lock:data:" + orderNo;
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        Boolean isUnlock = redisTemplate.opsForValue().setIfAbsent(key, orderNo, 300, TimeUnit.SECONDS);
        try{
            if(Boolean.TRUE.equals(isUnlock)){
                // 解锁库存
                List<SkuLockVo> skuLockVoList = (List<SkuLockVo>) redisTemplate.opsForValue().get(dataKey);
                for (SkuLockVo skuLockVo : skuLockVoList) {
                    skuStockMapper.unlock(skuLockVo.getSkuId(), skuLockVo.getSkuNum());
                }
                redisTemplate.delete(dataKey);
            }
            channel.basicAck(deliveryTag, false);
        }catch (Exception e){
            channel.basicNack(deliveryTag, false, true);
        }
    }
}
